﻿#include <iostream>
#include <fstream>
#include "MdSpi.h"
#include "TdSpi.h"
#include "Strategy.h"
#include <mutex>
#include <ThostFtdcMdApi.h>
//#include "ThostFtdcUserApiDataType.h" 都已被继承了
//#include "ThostFtdcUserApiStruct.h"   都已被继承了

using namespace std;

std::map<std::string, std::string> accountConfig_map;//保存账户信息的表
std::map<std::string, std::string> contracts_map;//保存账户信息的表

TdSpi* g_pUserTDSpi = nullptr;//全局交易类指针

std::mutex m_mutex;

void ReadConfigMap(map<std::string, std::string>& accountmap);
void ReadContracts(map<std::string, std::string>& contractmap);

//全局的订阅合约向量
std::vector<std::string> subscribe_inst_vec;

int g_nRequestID = 0;

int main()
{
	cerr << "---------------------------------------------" << endl;
	cerr << "---------------------------------------------" << endl;
	cerr << "-------------CTP高频交易系统引导-------------" << endl;
	cerr << "---------------------------------------------" << endl;
	cerr << "---------------------------------------------" << endl;
	//-----------------1、读取账户和订阅合约信息-------------------
	ReadConfigMap(accountConfig_map);
	ReadContracts(contracts_map);
	//-----------------2、创建行情Api和回调类实例------------------------
	//-----------------参考ctp函数手册中的行情/交易接口API---------------
	CThostFtdcMdApi* pUserApi_market = CThostFtdcMdApi::CreateFtdcMdApi("./CtpTmp/MarketFlow/");
	const char* ver_Md = CThostFtdcMdApi::GetApiVersion();
	printf("行情API版本：%s\n",ver_Md);
	MdSpi* pUserSpi_market = new MdSpi(pUserApi_market);
	pUserApi_market->RegisterSpi(pUserSpi_market);

	char mdFront[50];
	strcpy_s(mdFront,sizeof(mdFront),accountConfig_map["MarketFront"].c_str());
	pUserApi_market->RegisterFront(mdFront);
	//pUserApi_market->Init();//发送行情接口连接请求,在 TdSpi::OnRspQryInstrument() 启动了

	//-----------------3、创建交易Api和回调类实例------------------------
	//class TRADER_API_EXPORT CThostFtdcTraderApi 先创建Api
	CThostFtdcTraderApi* pUserApi_trade = CThostFtdcTraderApi::CreateFtdcTraderApi("./CtpTmp/TradeFlow/");
	//const char* ver_td = cthostftdctraderapi::getapiversion(); //获取版本号，提醒随时更新版本
	//printf("交易api版本：%s\n",ver_td);
	TdSpi* pUserSpi_trade = new TdSpi(pUserApi_trade, pUserApi_market, pUserSpi_market);
	pUserApi_trade->RegisterSpi(pUserSpi_trade);//api注册回调类

	pUserApi_trade->SubscribePublicTopic(THOST_TERT_RESTART);//订阅公有流
	pUserApi_trade->SubscribePrivateTopic(THOST_TERT_QUICK);//订阅私有流


	char tdFront[50];
	strcpy_s(tdFront,sizeof(tdFront),accountConfig_map["TradeFront"].c_str());
	pUserApi_trade->RegisterFront(tdFront);
	pUserApi_trade->Init();//发送交易接口连接请求，TdApi线程引导了MdApi线程，如果46行注释了的话

	g_pUserTDSpi = pUserSpi_trade; 

	pUserApi_market->Join();
	pUserApi_trade->Join();

	pUserApi_market->Release();
	pUserApi_trade->Release();
	
	return 0;
}
void ReadConfigMap(map<std::string, std::string>& accountmap)
{
	std::ifstream file1(".\\x64\\Debug\\config.txt", ios::in);
	string fieldKey;
	string fieldValue;
	char dataLine[256];
	if (!file1)
	{
		cout << "配置文件不存在" << endl;
		return;
	}
	else
	{
		while (file1.getline(dataLine, sizeof(dataLine), '\n'))
		{
			int length = strlen(dataLine);
			char tmp[128];
			for (int i = 0, j = 0, count = 0; i < length + 1; i++)
			{
				if (dataLine[i] != ',' && dataLine[i] != '\0')
					tmp[j++] = dataLine[i];
				else
				{
					//appid, simnow_client_test
					//authcode, 0000000000000000
					tmp[j] = '\0';

					count++;
					//cout << "count: " << count << ",tmp :" << tmp << endl;
					j = 0;
					switch (count)
					{
					case 1:
						fieldKey = tmp;
						break;
					case 2:
						fieldValue = tmp;
					default:
						break;
					}
				}
			}//while结束
			accountmap.insert(make_pair(fieldKey, fieldValue));


		}
	}


	file1.close();
}
void ReadContracts(map<std::string, std::string>& contractmap)
{
	std::ifstream file2(".\\x64\\Debug\\contracts.txt", ios::in);
	string fieldKey;
	string fieldValue;
	char dataLine[256];
	if (!file2)
	{
		cout << "配置文件不存在" << endl;
		return;
	}
	else
	{
		while (file2.getline(dataLine, sizeof(dataLine), '\n'))
		{
			int length = strlen(dataLine);
			char tmp[128];
			for (int i = 0, j = 0, count = 0; i < length + 1; i++)
			{
				if (dataLine[i] != ',' && dataLine[i] != '\0')
					tmp[j++] = dataLine[i];
				else
				{

					tmp[j] = '\0';
					count++;
					j = 0;
					switch (count)
					{
					case 1:
						fieldKey = tmp;
						break;
					case 2:
						fieldValue = tmp;
					default:
						break;
					}
				}
			}
			contractmap.insert(make_pair(fieldKey, fieldValue));
		}
	}
	file2.close();
}

